function [params data stimSet] = AdaptID_v1_2_LongTermBeha(expInfo)
%AdaptID_v1_2_LongTermBeha: Call the AdaptID_v1_2  driver for face stimuli
%           [params data stimSet] = AdaptID_v1_2_LongTermBeha(expInfo)
%
%           AdaptID_v1_2_LongTermBeha(expInfo) initializes the driver for the
%   AdaptID_v1_2 experiment. This file should not be called directly.
%   Instead, it should be called from the AdaptID_v1_2() function.
%           The driver reads the experimental parameters, sets up the
%   screen, load the stimuli, and run the experiment. It also collects and
%   saves the relevant data.
%
%
%   Inputs
%   -------
%   expInfo: contains all the experimental information necessary for
%           execution, including the experimental protocol to be ran
%
%   Outputs
%   -------
%   params: Experimental parameters, read from an external file specified
%           on the protocol file
%   data: Data collected during execution, including subject responses,
%           reaction times, and all presentation times
%   stimSet: Information about the stimuli that were presented
%
%   _______________________________________________
%   by Marcelo G Mattar (10/01/2012)
%   mattar@sas.upenn.edu


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% MAIN
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

try
    % Setup basic parameters for the experiment.
	params = initParams(expInfo);
    
    % Make sure this is the correct protocol and check number of expected TRs
    fprintf('\nThis is protocol %d - %s. Expecting %d trials.\n- Press any key to continue.\n\n',expInfo.protocolIndex,expInfo.protocol.protocolList(expInfo.protocolIndex).name,params.sequence.numTrials);
    KbWait(-3,2);
    
	% Setup the display.
	[window, params] = initDisplay(params);
    
	% Load the stimuli.
    stimSet = loadStimuli(params);
    
	data = experimentLoop(expInfo, params, stimSet, window);
    
    % Print concluding message and close the screen
    fprintf('\nProtocol %d - %s is complete, with %d trials.\n\n',expInfo.protocolIndex,expInfo.protocol.protocolList(expInfo.protocolIndex).name,params.sequence.numTrials);
    GiveBackTheScreen;
    
catch exception
    GiveBackTheScreen(true);
    fprintf('\nIncomplete data. Attempted to save partial data...\n');
    fprintf('\n- Data saved to %s\n\n', expInfo.dir.saveFileName);
     
	if strcmp(exception.message, 'abort')
		fprintf('- Aborting experiment.\n');
	else
		rethrow(exception);
	end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPERIMENT LOOP
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function data = experimentLoop(expInfo, params, stimSet, window)

    % Save starting time
    data.timing.expStart = GetSecs;

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % INITIAL SETUP

    % Define some important variables
    data.numTrials = params.sequence.numTrials;
    data.seq = params.sequence.sequence;
    
    % Preallocate experimental data variables
    data.timing.stimOnsetTime = nan(1,data.numTrials);
    data.timing.stimOffsetTime = nan(1,data.numTrials);
    data.timing.stimDuration = nan(1,data.numTrials);
    data.timing.trialOnset = nan(1,data.numTrials);
    data.timing.trialDuration = nan(1,data.numTrials);
    
    data.timing.respTime = nan(1,data.numTrials);
    data.timing.reacTime = nan(1,data.numTrials);
    data.respKey = cell(1,data.numTrials);

    % Make stimuli textures
    display('Making stimuli textures...');
    imgPtr = zeros(size(stimSet));
    for i=1:size(stimSet,1)
        for j=1:size(stimSet,2)
            imgPtr(i,j) = Screen('MakeTexture',window,stimSet{i,j});
        end
    end
    display('Done!');
    
    % Preload textures into VRAM to facilitate fast drawing
    Screen(window, 'PreloadTextures');

    % Create fixation cross
    FixCross = [params.screen.Xcenter-params.fixPoint.fpThickness,params.screen.Ycenter-params.fixPoint.fpSize,params.screen.Xcenter+params.fixPoint.fpThickness,params.screen.Ycenter+params.fixPoint.fpSize;params.screen.Xcenter-params.fixPoint.fpSize,params.screen.Ycenter-params.fixPoint.fpThickness,params.screen.Xcenter+params.fixPoint.fpSize,params.screen.Ycenter+params.fixPoint.fpThickness];

    % Present screen with instructions for the scan and a sample of the target
    displayText(window, params.main.instructionFile, params.screen.lineSpacing, params.screen.fontSize, params.screen.fontColor)
    Screen(window,'Flip');

    % Prepare the blank screen with fixation cross
    Screen(window,'FillRect',params.screen.bgColor);
    Screen('FillRect', window, params.fixPoint.fpColor, FixCross');
    
    % Wait for subject's input to begin experiment:
    fprintf('\nWaiting for subject''s input to begin experiment...\n- Ask subject to press any button.\n\n');
    KbStrokeWait(-3);
    Screen(window,'Flip');
    
    % Wait for the first 't'
    %fprintf('Waiting for the first ''t''...\n- Ask technician to begin scan.\n\n');
    %data.timing.scanStart = WaitForT;

    % Begin trials
    for trial = 1:data.numTrials
        
        % Save trial Onset time
        data.timing.trialOnset(trial) = GetSecs();
        
        % Save partial data (in case an error occurs)
        save(expInfo.dir.saveFileName, 'expInfo', 'params', 'data');
        
        if data.seq(trial) == 0
            fprintf('Stimulus #%d: (-Blank-)\n',trial);
        elseif data.seq(trial) < 0
            fprintf('Stimulus #%d: (-TARGET-)\n',trial);
        else
            fprintf('Stimulus #%d: (%d) - Image: %s\n', trial, data.seq(trial), params.stimuli.filename{params.sequence.fileIndex(trial),data.seq(trial)});
        end
        fprintf('----------------------------------\n');

        % If the current trial is not a blank
        if data.seq(trial) ~= 0
            

            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % STIMULUS SCREEN PREPARATION
            
            % Prepare stimulus texture
            if data.seq(trial) ~= -1 % If current stimulus is not a target
                Screen('DrawTexture',window,imgPtr(params.sequence.fileIndex(trial),data.seq(trial)), [], CenterRect([0 0 params.stimuli.stimDimPx(1) params.stimuli.stimDimPx(2)], params.screen.screenRect));
            else % If the current stimulus IS a target
                Screen('DrawTexture',window,imgPtr(params.sequence.fileIndex(trial-1),data.seq(trial-1)), [], CenterRect([0 0 params.stimuli.stimDimPx(1) params.stimuli.stimDimPx(2)], params.screen.screenRect));
            end
            
            % Prepare fixation cross
            Screen('FillRect', window, params.fixPoint.fpColor, FixCross');
            

            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % STIMULUS PRESENTATION
            
            % Flip the screen
            data.timing.stimOnsetTime(trial) = Screen(window,'Flip');


            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % WAIT FOR T IF trial=SyncTrial, OTHERWISE WAIT FOR TIMEOUT
            
            % Wait params.timing.stimDuration (stimulus presentation duration) minus half a flipInterval (to compensate for delays and refresh at the right time)
            [respTime, respKey] = WaitForTrialAndListenToResp(data.timing.stimOnsetTime(trial), params.timing.stimDuration - (params.screen.flipInterval/2)*1000, ~isempty(data.respKey{trial}));
            
            % If a response was received (and no other response for this trial was saved before)
            if (isnan(data.timing.respTime(trial)) && ~isnan(respTime))
                data.respKey{trial} = respKey(1);
                data.timing.respTime(trial) = respTime;
            end


            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % BLANK SCREEN PREPARATION
            
            % Prepare the blank screen
            Screen(window,'FillRect',params.screen.bgColor);
            
            % Prepare fixation cross
            Screen('FillRect', window, params.fixPoint.fpColor, FixCross');


            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % BLANK SCREEN PRESENTATION
            
            % Wait until the end of the trial
            data.timing.stimOffsetTime(trial) = Screen(window,'Flip');


            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % WAIT FOR T IF trial=SyncTrial, OTHERWISE WAIT FOR TIMEOUT
            
            % Wait params.timing.trialDuration-params.timing.stimDuration (blank period duration minus half a flipInterval (to compensate for delays and refresh at the right time)
            [respTime, respKey] = WaitForTrialAndListenToResp(data.timing.trialOnset(trial), params.timing.trialDuration, ~isempty(data.respKey{trial}));
            
            % If a response was received (and no other response for this trial was saved before)
            if (isnan(data.timing.respTime(trial)) && ~isnan(respTime))
                data.respKey{trial} = respKey(1);
                data.timing.respTime(trial) = respTime;
            end
            
            
        % If the current trial is a "null" trial
        elseif data.seq(trial) == 0
            
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % BLANK SCREEN PREPARATION
            
            % Prepare the blank screen
            Screen(window,'FillRect',params.screen.bgColor);
            
            % Prepare fixation cross
            Screen('FillRect', window, params.fixPoint.fpColor, FixCross');


            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % BLANK SCREEN PRESENTATION
            
            % Wait until the end of the trial
            Screen(window,'Flip');


            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            % WAIT FOR T IF trial=SyncTrial, OTHERWISE WAIT FOR TIMEOUT
            
            % Wait params.timing.trialDuration minus half a flipInterval (to compensate for delays and refresh at the right time)
            [respTime, respKey] = WaitForTrialAndListenToResp(data.timing.trialOnset(trial), params.timing.trialDuration, ~isempty(data.respKey{trial}));
            
            % If a response was received (and no other response for this trial was saved before)
            if (isnan(data.timing.respTime(trial)) && ~isnan(respTime))
                data.respKey{trial} = respKey(1);
                data.timing.respTime(trial) = respTime;
            end
            
        end
        
        


        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % WRAP-UP TRIAL
        
        if data.seq(trial) ~= 0
            % Calculate reaction time
            data.timing.reacTime(trial) = 1000*(data.timing.respTime(trial) - data.timing.stimOnsetTime(trial));
            % Calculate stimulus duration
            data.timing.stimDuration(trial) = data.timing.stimOffsetTime(trial)-data.timing.stimOnsetTime(trial);
        end
        % Calculate trial duration
        data.timing.trialDuration(trial) = GetSecs()-data.timing.trialOnset(trial);
        
        % Print trial summary
        if ~isnan(data.timing.stimDuration(trial))
            fprintf('Presentation duration: %6.2f ms\n', data.timing.stimDuration(trial)*1000);
        end
        if ~isnan(data.timing.trialDuration(trial))
            fprintf('Trial duration: %6.2f ms\n', data.timing.trialDuration(trial)*1000);
        end
        if ~isnan(data.timing.reacTime(trial))
            fprintf('Reaction time: %.2f ms\n', data.timing.reacTime(trial));
            
            % Make sure reaction times are being calculated properly
            if data.timing.reacTime(trial) > 2*params.timing.trialDuration
                fprintf('\n**********************************************************\n');
                fprintf('WARNING! REACTION TIMES ARE NOT BEING CALCULATED PROPERLY!\n');
                fprintf('**********************************************************\n');
            end
        end
        %fprintf(progressBar(data.timing.TRstatus, data.timing.respTime, data.correctResp, trial));
        
        fprintf('\n');

    end
    
    data.timing.expEnd = GetSecs;
    data.timing.expDuration = data.timing.expEnd - data.timing.expStart;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% INITIALIZE PARAMETERS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function params = initParams(expInfo)
    % Load the config file for this condition.
    cfgFile = ConfigFile(expInfo.protocol.configFileName);

    % Convert all the ConfigFile parameters into simple struct values.
    params = convertToStruct(cfgFile.Params);

    % Complete the path to instruction and sequence files
    params.main.instructionFile = sprintf('%s/%s', expInfo.dir.configDir, params.main.instructionFile);
    params.sequence.sequenceFile = sprintf('%s/%s', expInfo.dir.configDir, params.sequence.sequenceFile);
    params.sequence.stimRandPerm = sprintf('%s/%s', expInfo.dir.configDir, params.sequence.stimRandPerm);
    
    % Import sequences
    params.sequence.sequence = double(importdata(params.sequence.sequenceFile));
    params.sequence.stimRandPerm = double(importdata(params.sequence.stimRandPerm));

    % Save number of trials and labels
    params.sequence.numTrials = length(params.sequence.sequence);
    params.sequence.numLabels = length(unique(params.sequence.sequence));

    % Get screen information
    params.screen.screenNum  = max(Screen('screens')); % Get the number of the last screen
    params.screen.screenRect = Screen(params.screen.screenNum, 'rect'); % Get local rect coordinates of screen
    params.screen.stimRect = CenterRect([0 0 params.stimuli.stimDimPx(1) params.stimuli.stimDimPx(2)], params.screen.screenRect); % Find coordinates of a centralized rectangle for stimuli
    [params.screen.Xcenter,params.screen.Ycenter] = RectCenter(params.screen.screenRect);

    % Calculate visual angles
    params.screen.screenDimVD = (180/pi)*2*atan(params.screen.screenDimCM/(2*params.screen.screenDistanceCM)); % Screen dimensions in visual angles (degrees)
    params.stimuli.stimDimVD = (params.screen.screenDimVD).*((params.stimuli.stimDimPx)./(params.screen.screenRect(1,3:4))); % Stimuli dimensions in visual angles (degrees)
    
    % Generate full directory name(s) where stimuli are located
    params.stimuli.subdirFull = cell(length(params.stimuli.stimGroups),1);
    for i=1:length(params.stimuli.stimGroups)
        params.stimuli.subdirFull{i,1} = [expInfo.dir.stimDir '/' params.stimuli.stimSubDirectory num2str(params.stimuli.stimGroups(i)) '/'];
    end
    
    % Test if all stimulus subdirectories exist
    allFileNamesInThisDirectory = cell(1,length(params.stimuli.subdirFull));
    availableFilesInThisDirectory = zeros(1,length(params.stimuli.subdirFull));
    for thisDir=1:length(params.stimuli.subdirFull)
        if ~exist(params.stimuli.subdirFull{thisDir,1},'dir')
            error('One or more of the directories specified in the config file do not exist');
        end
        
        % Retrieve all files in the current directory
        allFileNamesInThisDirectory{1,thisDir} = dir(params.stimuli.subdirFull{thisDir,1});
        % Remove the '.' and '..' directories
        allFileNamesInThisDirectory{1,thisDir} = allFileNamesInThisDirectory{1,thisDir}(3:end);
        % Remove any other unimportant directory
        if strcmp(allFileNamesInThisDirectory{1,thisDir}(1).name,'.DS_Store');
            allFileNamesInThisDirectory{1,thisDir} = allFileNamesInThisDirectory{1,thisDir}(2:end);
        end
        if strcmp(allFileNamesInThisDirectory{1,thisDir}(1).name,'.svn');
            allFileNamesInThisDirectory{1,thisDir} = allFileNamesInThisDirectory{1,thisDir}(2:end);
        end
        availableFilesInThisDirectory(1,thisDir) = length(allFileNamesInThisDirectory{1,thisDir});
        
    end
    
    numStimAvailable = min(availableFilesInThisDirectory);
    params.stimuli.filename = cell(numStimAvailable,length(params.stimuli.subdirFull));
    % Select images and generate cell array with all stimuli to be used
    for thisDir=1:length(params.stimuli.subdirFull)
        for thisFile=1:numStimAvailable
            params.stimuli.filename{thisFile,thisDir} = [params.stimuli.subdirFull{thisDir,1} allFileNamesInThisDirectory{1,thisDir}(thisFile).name];
        end
    end
    
    % Check if the sequence requires more images than are available
    for thisGroup=1:length(params.stimuli.stimGroups)
        if (sum(params.sequence.sequence == params.stimuli.stimGroups(thisGroup)) > numStimAvailable)
            error('The sequence specified requires more stimuli than are available on %s/%s', expInfo.dir.stimDir, params.stimuli.stimSubDirectory);
        end
    end
    
    % Reshape the stimulus random permutation
    params.sequence.stimRandPerm = reshape(params.sequence.stimRandPerm,length(params.sequence.stimRandPerm)/length(params.stimuli.stimGroups),length(params.stimuli.stimGroups));
    
    % Generate a sequence of stimulus indexes
    params.sequence.fileIndex = zeros(size(params.sequence.sequence));
    for thisGroup=1:length(params.stimuli.stimGroups)
        params.sequence.fileIndex(params.sequence.sequence==thisGroup) = params.sequence.stimRandPerm(1:sum(params.sequence.sequence==thisGroup),thisGroup);
    end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% INITIALIZE DISPLAY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [window, params] = initDisplay(params)
    % Initialize Screen
    display(sprintf('\nInitializing screen...'));
    display(sprintf('The screen dimensions are %d x %d pixels, or %2.1f x %2.1f visual degrees.',params.screen.screenRect(3),params.screen.screenRect(4),params.screen.screenDimVD(1),params.screen.screenDimVD(2)));
    display(sprintf('Stimuli dimensions are %2.1f x %2.1f visual degrees.',params.stimuli.stimDimVD(1),params.stimuli.stimDimVD(2)));

    Screen('Preference', 'SkipSyncTests', 0);
    window = Screen(params.screen.screenNum,'OpenWindow',params.screen.bgColor,params.screen.screenRect,32);
    Screen('BlendFunction', window, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    Priority(MaxPriority(window)); % Set up window as maximum priority
    ListenChar(2); % Enable character listening; additionally any output of keypresses to Matlab windows is suppressed
    HideCursor; % Hide mouse cursor from the screen
    WaitSecs(1); % Wait for display to stabilize

    params.screen.screenFrameRate = FrameRate(params.screen.screenNum);
    params.screen.flipInterval = Screen('GetFlipInterval', window);
    Screen(window,'TextFont', 'Courier'); % Set up font type
    Screen(window,'TextSize',params.screen.fontSize); % Set up font size
    Screen(window,'DrawText','Please wait, loading...', 50, 50, [0, 0, 0]); % Draw "please wait" text
    Screen(window,'Flip'); % Display everything on the window
    FlushEvents; % Clear the buffer

    display(sprintf('Done!'));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LOAD STIMULI
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function stimSet = loadStimuli(params)

    display(sprintf('\nLoading stimuli...'));
    
    % Load stimuli
    stimSet = cell(size(params.stimuli.filename));
    for i=1:size(params.stimuli.filename,1)
        for j=1:size(params.stimuli.filename,2)
            [luminImg, ~, alphaImg] = imread(params.stimuli.filename{i,j});
            stimSet{i,j}(:,:,1:3) = luminImg;
            stimSet{i,j}(:,:,4) = alphaImg;
        end
    end
    display('Done!');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%






%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% AUXILIARY FUNCTIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function cfStruct = convertToStruct(CFParams)
    % cfStruct = convertToStruct(CFObj)
    %
    % Description:
    % Converts all parameters contained in the ConfigFile object into a struct.
    %
    % Required Inputs:
    % CFObj (ConfigFile) - The ConfigFile object to operate on.
    %
    % Output:
    % cfStruct (struct) - Struct containing all ConfigFile items and their
    %    associated data.

    if nargin ~= 1
        error('Usage: cfStruct = convertToStruct(CFObj)');
    end

    for i = 1:length(CFParams)
        paramClass = CFParams(i).paramClass;
        paramName = CFParams(i).paramName;
        paramVal = CFParams(i).paramVal;

        cfStruct.(paramClass).(paramName) = paramVal;
    end



function GiveBackTheScreen(prej)

    if nargin == 0
        prej = false;
    end
    if prej
        fprintf('\n\nTerminated with extreme prejudice!\n');
    end
    Priority(0);
    Screen('CloseAll');
    ShowCursor;
    ListenChar;
        
        

function [respTime, respKey] = WaitForTrialAndListenToResp(t0, intervalDuration, respStatus)
    %
    %t0: time when the function was called
    %intervalDuration (in ms)

    FlushEvents;
    respTime = NaN;
    respKey = NaN;
    resp_key = [30:39 KbName('1'):KbName('9')];

    while (GetSecs()-t0) < intervalDuration/1000
        % Check all keyboards and keypads (-3) status
        [keyIsDown, secs, keyCode, ~] = KbCheck(-3);
        if keyIsDown % If *any* key is down
            % If any response key is one of the keys being pressed
            if isnan(respTime) && any(ismember(resp_key,find(keyCode))) && (respStatus==0)
                respTime = secs;
                respKey = KbName(resp_key(ismember(resp_key,find(keyCode,1))));
                fprintf('*** Key pressed: %c ***\n',respKey(1));
            end
            % If q is one of the keys being pressed  
            if ismember(KbName('q'),find(keyCode))
                error('Experimenter pressed q to terminate.');
            end
        end
    end



function displayText(window, filename, linespacing, fontsize, fontcolor)
    % draws the text in file <filename> to the screen.
    % <filename> must have no empty lines.
    % Include a space if an empty line is desired
    textfid=fopen(filename);
    lCounter = 1;
    Screen(window,'TextSize',fontsize);

    while 1
        tline = fgetl(textfid);
        if ~ischar(tline), break, end

        if tline(1) ~= '.'
            Screen(window, 'DrawText',tline, 50, 50 + (lCounter-1)*linespacing, fontcolor);
        end
        lCounter = lCounter + 1;
    end
    fclose(textfid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
